/****************************************************
文件：ViewBase.cs
作者：UnitySir
邮箱：zouajck@foxmail.com
日期：2021/04/28 10:57:00
功能：Nothing
*****************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using DSFramework;
using UnityEngine;
using UnityEngine.UI;

public abstract class DSViewBase : DSComponent
{
    #region FindComponent

    /// <summary>
    /// 组件缓存
    /// </summary>
    protected Dictionary<string, List<Component>> CmptNameDic { get; set; }

    protected Dictionary<string, List<Component>> CmptTagDic { get; set; }

    private void Awake()
    {
        CmptNameDic = new Dictionary<string, List<Component>>();
        CmptTagDic = new Dictionary<string, List<Component>>();
        DSFindCmpt<Image>();
        DSFindCmpt<Button>();
        DSFindCmpt<InputField>();
        DSFindCmpt<Text>();
        DSFindCmpt<Toggle>();
        DSFindCmpt<RawImage>();
        DSFindCmpt<Slider>();
        DSFindCmpt<Dropdown>();
        DSFindCmpt<Scrollbar>();
        DSFindCmpt<Animation>();
        DSFindCmpt<Animator>();
        DSFindCmpt<AudioSource>();
        DSFindCmpt<Transform>();
        DSFindCmpt<CharacterController>();
        DSFindCmpt<Rigidbody>();
        Init();
    }

    protected abstract void Init();

    private void DSFindCmpt<T>() where T : Component
    {
        DSFindComponentsInChildren4Name<T>();
        DSFindComponentsInChildren4Tag<T>();
    }

    /// <summary>
    /// 根据名称查找子物体
    /// </summary>
    /// <typeparam name="T"></typeparam>
    private void DSFindComponentsInChildren4Name<T>() where T : Component
    {
        T[] controls = GetComponentsInChildren<T>(true);
        foreach (var t in controls)
        {
            var objName = t.gameObject.name;
            if (CmptNameDic.ContainsKey(objName))
            {
                CmptNameDic[objName].Add(t);
            }
            else
            {
                CmptNameDic.Add(t.gameObject.name, new List<Component> {t});
            }
        }
    }

    /// <summary>
    /// 根据标签查找子物体
    /// </summary>
    /// <typeparam name="T"></typeparam>
    private void DSFindComponentsInChildren4Tag<T>() where T : Component
    {
        T[] controls = GetComponentsInChildren<T>(true);
        foreach (var t in controls)
        {
            var objTag = t.gameObject.tag;
            if (CmptTagDic.ContainsKey(objTag))
            {
                CmptTagDic[objTag].Add(t);
            }
            else
            {
                CmptTagDic.Add(t.gameObject.tag, new List<Component> {t});
            }
        }
    }

    /// <summary>
    /// 通过名称获取该对象下的子对象
    /// </summary>
    /// <param name="objName"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    protected T DSGetO4Name<T>(string objName) where T : Component
    {
        try
        {
            int len = CmptNameDic[objName].Count; //获取到组件列表的长度
            for (int i = 0; i < len; i++)
            {
                if (CmptNameDic[objName][i] is T cpt)
                {
                    return cpt;
                }
            }
        }
        catch
        {
            throw new Exception($"没有找到该组件:{objName},请确定名称是否正确!");
        }

        return null;
    }

    /// <summary>
    /// 通过标签获取该物体的子对象
    /// </summary>
    /// <param name="objTag"></param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    protected T DSGet4Tag<T>(string objTag) where T : Component
    {
        try
        {
            int len = CmptTagDic[objTag].Count; //获取到组件列表的长度
            for (int i = 0; i < len; i++)
            {
                if (CmptTagDic[objTag][i] is T cpt)
                {
                    return cpt;
                }
            }
        }
        catch
        {
            throw new Exception($"没有找到该组件:{objTag},请确定名称是否正确!");
        }

        return null;
    }

    #endregion
}